NaCl
NaCl需要在SDK和NaCl构造方式的NW中使用 , 参考[构造方式](Build Flavors.md) .
NW.js同Chromium一样支持NaCl(本地客户端)以及PNaCl(便携本地客户端) . 应用可以嵌入NaCl和PNaCl .
以下文档说明由[Chrome NaCl 文档](https://developer.chrome.com/native-client/devguide/tutorial/tutorial-part1)提供 .
概述
该文档说明了如何使用PNaCl构建以及运行一个网页应用 . 该客户端应用使用HTML , JavaScript和C++编写的本地模块进行开发 . 页面能够使用PNaCl提供的工具运行本地客户端模块 .
阅读该文档说明之前 , 建议先了解本地客户端技术相关信息 .
文档应用需求
文档中的应用展示如何在页面加载一个本地客户端模块 , 如何在JavaScript和本地客户端模块之间发送消息 . 该应用使用JavaScript发送'hello'
信息给本地客户端模块 . 当本地客户端模块接收到信息之后 , 检查接收到的信息是否为'hello'
字符串 . 如果是 , 本地客户端模块返回'hello from NaCl'
信息 . JavaScript接收到返回的信息之后进行打印 .
JavaScript和本地客户端模块通信
本地客户端模块支持双向通信 , 既能够在JavaScript和本地客户端模块之间进行通信 , 两端能够发起以及接收信息 . 所有通信过程都是异步完成:呼叫者(JavaScript或本地客户端模块)发送信息 , 但是呼叫者不会等待 , 甚至不期望响应 . 该过程类似于网页请求中的客户端和服务器之间的通信 , 客户端发送消息给服务器之后立刻返回 . 本地客户端通信系统是Pepper API的一部分 , 参考通信系统开发者指南. 该页面工作方式也是JavaScript中document之间的工作方式 .
步骤 1: 下载以及安装本地客户端SDK
参考说明下载及安装本地客户端SDK .
步骤 2: Start a local server
模拟生产环境 , SDK中提供一个页面服务 , 可以通过localhost
访问 . 可以通过Makefile调用serve
运行该服务:
$ cd pepper_$(VERSION)/getting_started
$ make serve
SDK中可能包含多个Chrome/Pepper版本 , 参考[版本](https://developer.chrome.com/native-client/version.html) . 可以使用`pepper_$(VERSION)`调用指定版本 , 如`pepper_37` . 如果不知道使用哪个版本 , 可以通过`naclsdk list`命令查看稳定版本 . 参考[本地客户端SDK下载](https://developer.chrome.com/native-client/sdk/download.html) .
如果没有指定端口 , 服务默认端口为5103 , 可以使用http://localhost:5103进行访问 .
提供的服务目的是为了开发 , SDK并不是必须的 .
步骤 3: Set up the Chrome browser 启动Chrome浏览器
PNaCl默认开启Chrome浏览器 . 建议使用与Chrome浏览器相同版本 , 或者版本高于SDK构建本地客户端模块 . 低版本PNaCl模块能够在高版本的Chrome浏览器中工作 , 反之将不能正常工作 .
可以在浏览器中输入`about:chrome`查看Chrome浏览器版本信息 .
根据开发经验 , 建议关闭Chrome浏览器缓存 . 缓存资源优先级高 ; 关闭缓存能够确保最新版本的本地模块能够被加载 .
菜单
>工具
>开发者工具
, 打开Chorme浏览器的开发者工具 .- 点击Chrome窗口右下角齿轮图标按钮 .
- 通用设置中 , “Disable cache (while DevTools is open)”选中 .
- 开发本地客户端应用过程中 , 一直开启开发者工具面板 .
Step 4: 样例代码
样例代码在SDK中可以使用 , 代码在路径pepper_$(VERSION)/getting_started/part1
. 包含以下文件:
index.html
: 包括页面样式布局 , JavaScript与本地客户端模块之间通信 . 本地客户端包含在<embed>
标签中 , 指向一个配置文件 .hello_tutorial.nmf
: 配置文件 , 指向HTML文件以及本地客户端模块 , 同时可以额外为PNaCl配置命令 , 作为Chrome浏览器的一部分 .hello_tutorial.cc
: 本地客户端模块的C++代码 .MakeFile
: 编译文件 , 将hello_tutorial.cc
中的C++代码编译为pexe(便携可执行文件)
样例代码中有大量的说明解析代码的结构以及内容 . 更多关于本地客户端应用结构的描述 , 参考应用结构
样例代码有意简短编写 . C++代码除了正确初始化 , 并没有完成其他工作 . JavaScript代码等待本地客户端模块的加载以及将状态信息显示在页面中 .
步骤 5: 编译本地客户端模块以及运行样例应用
使用make
命令编译本地客户端模块:
$ cd pepper_$(VERSION)/getting_started/part1
$ make
样例包含在SDK目录结构中 , Makefile编译文件知道如何使用PNaCl工具自动完成编译工作 .
如果需要在SDK目录结构之外完成编译工作 , 需要设置$NACL_SDK_ROOT
环境变量支持 . 参考构建本地客户端模块 .
假设使用步骤 2开启了本地服务 , 可以在浏览器中输入http://localhost:5103/part1加载样例应用 . Chrome浏览器应该成功加载本地模块 , 并且页面中状态信息显示从“LOADING...”变为“SUCCESS” . 如果运行出错 , 使用排查步骤进行查看 .
步骤 6: JavaScript给本地客户端发送消息
该步骤中 , 修改网页文件(index.html
)完成页面加载模块之后能够发送消息给本地客户端 .
找到JavaScript函数moduleDidLoad()
, 添加发送‘hello’信息代码 , 如下:
function moduleDidLoad() {
HelloTutorialModule = document.getElementById('hello_tutorial');
updateStatus('SUCCESS');
// 发送消息给本地客户端模块
HelloTutorialModule.postMessage('hello');
}
步骤 7: 本地客户端实现信息处理
该步骤中 , 需要修改本地客户端模块hello_tutorial.cc
, 接收JavaScript发送的信息 , 之后响应相应的信息 . 特别说明:
- 模块实例中实现
HandleMessage()
方法 - 使用
PostMessage()
方法从模块发送信息给JavaScript代码 .
首先 , 定义本地客户端模块中需要使用的变量 , ‘hello’字符串为期望从JavaScript接收到的信息 , ‘hello from NaCl’字符串为本地客户端返回给JavaScript的字符串 . hello_tutorial.cc
文件中 , #include代码快之后加入一下代码:
namespace {
// 浏览器发送字符串
const char* const kHelloString = "hello";
// 接收信息之后返回给浏览器信息
const char* const kReplyString = "hello from NaCl";
} // 命名空间
现在 , 实现HandleMessage()
方法检查kHelloString
变量内容以及将kReplyString
作为结果进行返回 , 如下:
virtual void HandleMessage(const pp::Var& var_message) {
if (!var_message.is_string())
return;
std::string message = var_message.AsString();
pp::Var var_reply;
if (message == kHelloString) {
var_reply = pp::Var(kReplyString);
PostMessage(var_reply);
}
}
参考Pepper API文档 , 关于成员方法pp::Instance.HandleMessage和pp::Instance.PostMessage相关信息 .
步骤 8: 编译本地客户端模块及运行应用
- 再次使用
make
命令编译本地客户端模块 . - 运行
make serve
开启SDK服务 . - Chrome浏览器中重新加载http://localhost:5103/part1地址运行应用 .
Chrome浏览器加载本地客户端后 , 应该能够查看到信息由模块中发送 .
问题排查
如果应用不能运行 , 检查步骤 3 , 是否使用正确的环境 , 包括浏览器以及本地服务 . 确保当前运行的Chrome浏览器版本大于或者等于当前SDK版本 .
另外可以使用Chrome提供的JavaScript调试控制台 , 可以在Chrome工具菜单中进行配置 . 检查不能正确运行的原因 . 比如 , 信息如果是“NaCl module crashed” , 可能由于本地客户端模块存在问题 . 调试功能是使用该功能所必须的 .
更多关于问题排查的信息文档:
- 问题排查FAQ.
- Progress Events文档有关于问题事件解决相关信息 .
下一步
- 参考开发者指南中应用结构部分 , 获取关于如何构建本地客户端模块的相关说明 .
- 参考C++参考获取关于如何使用Pepper APIs的相关说明 .
- 查看SDK样例代码学习使用Pepper APIs编写其他功能的方法 .
- 参考Building , Running以及Debugging pages如何完成构建 , 运行以及调试本地客户端应用 .
- 参考naclports项目 , 提供使用其他可用本地客户端库 . 如果应用使用开源库 , 推荐使用naclport完成 .
以上内容适用CC-By 3.0 license